home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
boot
/
czesc_2
/
saferpatches
/
source.lha
/
Source
/
ShowPatch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-04
|
12KB
|
383 lines
typedef char CHAR;
#define LOCAL static
#define AND &&
#define OR ||
#define TEXTLENGTH 50
#define KICK204 37
#define ESC_KEY 27
/**************************************************************************/
/* LibHeader */
/* NextLib: Next library in a linked list. */
/* LibBase: Pointer to the libraries base (e.g. intuitionbase). */
/* Patches: Pointer to linked list of patches made to this library. */
/**************************************************************************/
struct LibHeader {
struct Library *LibBase;
struct Patches *Patches;
struct LibHeader *NextLib;
};
/************************************************************************/
/* Patches */
/* JMP : Opcode for JMP (used to call the old function). */
/* OldFunc : Address to the previus function (before SetFunction). */
/* NewFunc : The new function. */
/* Offset : Offset in library (Must be negativ). */
/* NextPatch: Pointer to next patch in list. */
/************************************************************************/
struct Patches {
USHORT JMP;
LONG OldFunc;
LONG NewFunc;
SHORT Offset;
struct Patches *NextPatch;
};
/**************************************************************************/
/* MyNode - is used to hold data to show. */
/* ExecNode : Standard exec node structure */
/* Text : array to put text inside (ExecNode.ln_Name points here) */
/**************************************************************************/
struct MyNode {
struct Node ExecNode;
char Text[TEXTLENGTH];
};
/************************/
/* All local functions */
/************************/
LOCAL VOID OpenFD(STRPTR LibName); /* Open .fd file corresponding to Libname */
LOCAL BOOL GetLine(CHAR *Buffer); /* Read one complete line from .fd file */
LOCAL VOID CloseFD(VOID); /* Close the .fd file */
LOCAL VOID BuildList(BOOL); /* Build the list of all known patches */
LOCAL VOID DestroyList(VOID); /* Remove the list */
LOCAL CHAR *AddNewNode(VOID); /* Create a new node and add it to the list */
LOCAL BOOL FindOffset(CHAR *BUFFER, SHORT OffsetToFind); /* Finds the function name */
LOCAL VOID OutputToWindow(VOID); /* Outputs in our own window */
LOCAL VOID OutputToCLI(VOID); /* Outputs to CLI (may be redirected */
/******************************/
/* The only exported function */
/******************************/
VOID MainLoop(BOOL,BOOL);
/******************************/
/* Our assembler functions */
/******************************/
extern struct LibHeader *FindPatches(VOID); /* Finds the SaferPatches program */
extern struct Window *OpenWindowWithGad(VOID); /* Open our window */
extern VOID CloseWindowWithGad(struct Window *Window); /* Closes our window */
extern VOID Bin2Hex(CHAR *, ULONG, UWORD); /* converts a long to ascii hex */
extern VOID Mystrncpy(CHAR *, CHAR *, UWORD); /* a small and fast strncpy */
/************************************************/
/* I dont have the 2.04 C includes so I have to */
/* declare the new functions here */
/************************************************/
struct IntuiMessage *GT_GetIMsg(struct Port *);
VOID GT_ReplyIMsg(struct IntuiMessage *);
VOID GT_BeginRefresh(struct Window *);
VOID GT_EndRefresh(struct Window *, BOOL);
CHAR FGetC(BPTR);
VOID StrToLong(CHAR *, ULONG *);
VOID WriteChars(CHAR *, ULONG);
VOID PutStr(CHAR *);
/************************************/
/* Pragmas for the above functions */
/************************************/
#pragma libcall GadToolsBase GT_GetIMsg 48 801
#pragma libcall GadToolsBase GT_ReplyIMsg 4e 901
#pragma libcall GadToolsBase GT_BeginRefresh 5a 801
#pragma libcall GadToolsBase GT_EndRefresh 60 802
#pragma libcall DOSBase FGetC 132 101
#pragma libcall DOSBase StrToLong 330 2102
#pragma libcall DOSBase WriteChars 3ae 2102
#pragma libcall DOSBase PutStr 3b4 101
#define IDCMP_CLOSEWINDOW CLOSEWINDOW
#define IDCMP_GADGETUP GADGETUP
#define IDCMP_VANILLAKEY 0x200000L
#define IDCMP_REFRESHWINDOW REFRESHWINDOW
/********************/
/* Global variables */
/********************/
extern BPTR Fh; /* File handle for .fd file */
extern LONG FDOffset; /* How far we have read in the .fd file */
extern struct Library *GadToolsBase; /* Library base */
extern struct DOSBase *DOSBase; /* Library base */
extern struct IntuitionBase *IntuitionBase; /* Library base */
extern struct List List; /* Exec list of ascii strings */
/****************************************************************/
/* MainProg(NoFD,UseWindow) */
/* NoFD - TRUE if we shouldn't look for FD files. */
/* UseWIndow - if TRUE open a window else output to console */
/****************************************************************/
VOID MainLoop(BOOL NoFD, BOOL UseWindow) {
BuildList(NoFD);
if (UseWindow)
OutputToWindow();
else
OutputToCLI();
DestroyList();
}
/****************************************************************/
/* OutputToWindow() - create a window with a LISTVIEW gadget */
/* - and present all patches there */
/****************************************************************/
LOCAL VOID OutputToWindow() {
BOOL KeepRunning = TRUE;
struct Window *Window;
if (IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library",KICK204)) {
if (GadToolsBase = OpenLibrary("gadtools.library",KICK204)) {
if (Window = OpenWindowWithGad()) {
do {
struct IntuiMessage *Msg;
WaitPort(Window->UserPort);
while (Msg = GT_GetIMsg(Window->UserPort)) {
ULONG Class = Msg->Class;
if (Class & (IDCMP_CLOSEWINDOW | IDCMP_GADGETUP))
KeepRunning = FALSE;
else if (Class & IDCMP_VANILLAKEY) {
UWORD Code = Msg->Code;
if (Code == ESC_KEY OR Code == 'X' OR Code == 'x')
KeepRunning = FALSE;
else
DisplayBeep(Window->WScreen);
}
else if (Class & IDCMP_REFRESHWINDOW) {
GT_BeginRefresh(Window);
GT_EndRefresh(Window,TRUE);
}
GT_ReplyIMsg(Msg);
}
}
while (KeepRunning);
CloseWindowWithGad(Window);
}
CloseLibrary(GadToolsBase);
}
CloseLibrary((struct Library *)IntuitionBase);
}
}
/******************************************************************/
/* OutputToCLI() - output all data to the default output stream */
/******************************************************************/
LOCAL VOID OutputToCLI() {
extern CHAR far LISTTEXT[];
struct MyNode *Node;
WriteChars(LISTTEXT,32);
PutStr("\n");
for (Node = (struct MyNode *)(List.lh_Head); Node->ExecNode.ln_Succ;
Node = (struct MyNode *)(Node->ExecNode.ln_Succ)) {
PutStr(Node->Text);
PutStr("\n");
}
}
/************************************************************************/
/* VOID BuildList(NoFD) - Build up a list of nodes each containing */
/* an ascii string describing one patch made */
/* NoFD - TRUE if we shouldn't look for .fd files */
/************************************************************************/
LOCAL VOID BuildList(BOOL NoFD) {
struct LibHeader *LocHeader;
NewList(&List);
if ((LocHeader = FindPatches()) != NULL) {
Forbid();
while (LocHeader = LocHeader->NextLib) {
struct Patches *Patch = LocHeader->Patches;
STRPTR LibName = LocHeader->LibBase->lib_Node.ln_Name;
CHAR FuncName[200]; /* hope this is enough */
CHAR *NodeText;
if (NodeText = AddNewNode()) {
strcpy(NodeText, "Library: ");
Mystrncpy(NodeText+9, LibName, TEXTLENGTH-10);
Fh = FDOffset = 0;
if (!NoFD)
OpenFD(LibName);
while (Patch = Patch->NextPatch) {
if (NodeText = AddNewNode()) {
Bin2Hex(NodeText , (ULONG)(-Patch->Offset), 4);
Bin2Hex(NodeText+ 6, Patch->NewFunc, 8);
Bin2Hex(NodeText+16, Patch->OldFunc, 8);
NodeText[4] = NodeText[5] = NodeText[14] = NodeText[15] =
NodeText[24] = NodeText[25] = ' ';
if (FindOffset(FuncName,-Patch->Offset))
Mystrncpy(NodeText+26, FuncName, TEXTLENGTH-27);
} /* if */
} /* while */
CloseFD();
} /* if */
} /* while */
Permit();
} /* if */
else {
CHAR *NodeText;
if (NodeText = AddNewNode())
strcpy(NodeText," SaferPatches not installed !");
}
}
/**********************************************************/
/* AddNewNode() - Create a new node and add it the list */
/* return - pointer to MyMode textfield */
/**********************************************************/
LOCAL CHAR *AddNewNode(VOID) {
struct MyNode *Node = AllocMem(sizeof(struct MyNode),MEMF_CLEAR);
if (Node) {
AddTail(&List,&Node->ExecNode);
return (Node->ExecNode.ln_Name = Node->Text)
}
return NULL;
}
/**********************************************************/
/* DestroyList() - remove all nodes and free memory used */
/**********************************************************/
LOCAL VOID DestroyList() {
struct Node *Node;
struct Node *Temp;
Node = List.lh_Head;
while (Temp = Node->ln_Succ) {
FreeMem(Node,sizeof(struct MyNode));
Node = Temp;
}
}
/********************************************************************************/
/* BOOL FindOffset(Buffer, OffsetToFind) - Walk through the open .fd file until */
/* we find the function corresponding to offset */
/* Buffer - Where to store function name */
/* OffSetToFind - */
/* return - TRUE if function found */
/********************************************************************************/
LOCAL BOOL FindOffset(CHAR *Buffer, SHORT OffsetToFind) {
extern CHAR far StdFunctions[];
if (OffsetToFind < 30) {
strcpy(Buffer,StdFunctions+((OffsetToFind-6)<<1));
return TRUE;
}
while (OffsetToFind > (SHORT)FDOffset) {
FDOffset += 6;
FOREVER {
if (GetLine(Buffer))
return FALSE;
if (Buffer[0] == '#') { /* command */
if (*((ULONG *)(Buffer+2)) == 0x62696173L) /* bias */
StrToLong(Buffer+6,&FDOffset);
}
else if (Buffer[0] > ' ' AND Buffer[0] != '*')
break;
}
}
/* remove anything beyond the first '(' */
if (OffsetToFind == (SHORT)FDOffset) {
while (*Buffer AND *Buffer != '(')
Buffer++;
*Buffer = 0;
return TRUE;
}
return FALSE;
}
/*********************************************************/
/* OpenFD(LibName) - Open a .fd file */
/* Libname - library (or device) to open .fd file for. */
/*********************************************************/
LOCAL VOID OpenFD(STRPTR LibName) {
TEXT FDFile[TEXTLENGTH];
CHAR *Temp = FDFile;
strcpy(FDFile,"FD:");
strcpy(FDFile+3,LibName);
while (*Temp != '.')
Temp++;
strcpy(Temp,"_lib.fd");
Fh = Open(FDFile, MODE_OLDFILE);
}
/********************************************/
/* CloseFD() - Closes the current .fd file */
/********************************************/
LOCAL VOID CloseFD() {
if (Fh) {
Close(Fh);
Fh = NULL;
}
}
/*****************************************************************/
/* BOOL GetLine(Buffer) - Reads one line from the open .fd file */
/* Buffer - where to store the line */
/* return - TRUE if end of file (EOF) */
/*****************************************************************/
LOCAL BOOL GetLine(CHAR *Buffer) {
if (Fh) {
CHAR tkn;
do {
tkn = FGetC(Fh);
if (tkn == EOF) {
CloseFD();
return TRUE;
}
}
while ((*Buffer++ = tkn) != '\n');
*Buffer = 0;
return FALSE;
}
return TRUE;
}